<template>
  <div class="page-cube">
    <div class="canvas"></div>
  </div>
</template>
<script setup name="texture">
import * as Three from "three";
import {onActivated, onDeactivated, onMounted, onUnmounted, reactive,} from 'vue';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
import {GUI} from 'dat.gui';

let state = reactive({
  gui: null,
  taskFlag: true,
  axesFlag: true,
  alpha: 0.5,
  cubeColor: '#ffffff',
});
let scene = new Three.Scene();
let axes = new Three.AxesHelper(5);
// 加载纹理
let textureLoader = new Three.TextureLoader();
let creeperTexture = textureLoader.load('/texture/creeper.jpg');
// 设置纹理重复方式为普通重复
creeperTexture.wrapS = Three.RepeatWrapping;
creeperTexture.wrapT = Three.RepeatWrapping;
// 设置纹理插值算法为直接使用最近颜色
creeperTexture.minFilter = Three.NearestFilter;
creeperTexture.magFilter = Three.NearestFilter;
let cubeGeometry = new Three.BoxGeometry(3, 3, 3,);
let cubeMaterial = new Three.MeshBasicMaterial({
  color: state.cubeColor,
  map: creeperTexture
});
let cube = new Three.Mesh(cubeGeometry, cubeMaterial);
let renderer = new Three.WebGLRenderer({antialias: true, alpha: true});
renderer.setClearColor('#c7ecee',);
renderer.setClearAlpha(state.alpha);
onMounted(() => {
  let dom = document.getElementsByClassName('canvas')[0];
  let width = dom.clientWidth;
  let height = dom.clientHeight;
  let camera = new Three.PerspectiveCamera(75, width / height, 0.1, 1000);
  camera.position.set(0, 0, 10);
  scene.add(camera);
  scene.add(axes);
  scene.add(cube);
  renderer.setSize(width, height);
  dom.appendChild(renderer.domElement);
  let controller = new OrbitControls(camera, renderer.domElement);
  controller.enableDamping = true;
  function render() {
    controller.update();
    renderer.render(scene, camera);
    state.taskFlag && requestAnimationFrame(render);
  }
  render();
});
onUnmounted(() => {
  state.taskFlag = false;
});
onActivated(() => {
  let gui = new GUI();
  gui.add(state, 'axesFlag').name('坐标轴').onChange(val => axes.visible = val);
  gui.add(state, 'alpha').name('透明度').max(1).min(0).step(0.1).onChange(val => renderer.setClearAlpha(val));
  gui.addColor(state, 'cubeColor').name('物体颜色').onChange(val => cube.material.color.set(val));
  let offset = gui.addFolder('纹理偏移');
  offset.add(creeperTexture.offset, 'x').max(1).min(-1).step(0.1);
  offset.add(creeperTexture.offset, 'y').max(1).min(-1).step(0.1);
  offset.open();
  let center = gui.addFolder('纹理旋转');
  center.add(creeperTexture.center, 'x').max(1).min(0).step(0.1);
  center.add(creeperTexture.center, 'y').max(1).min(0).step(0.1);
  center.add(creeperTexture, 'rotation').name('角度').max(Math.PI).min(-Math.PI).step(0.01);
  center.open();
  let repeat = gui.addFolder('重复');
  repeat.add(creeperTexture.repeat, 'x').step(1).max(5).min(1);
  repeat.add(creeperTexture.repeat, 'y').step(1).max(5).min(1);
  repeat.open();
  state.gui = gui;
});
onDeactivated(() => {
  state.gui.destroy();
});
</script>
<style lang="scss">
.page-cube {
  .canvas {
    width: 100%;
    height: 100%;
  }
}
</style>